use std::sync::Arc;

use super::{
    BootstrapLoader, DataSourceProvider, EventHandlerProvider, ExtensionProvider, ForgeConfigProvider, MetadataProvider, MiddlewareProvider,
    ProjectPhase, ProjectProfile, RuleProvider, data_source_stage_from_arc, event_handler_stage_from_arc, forge_config_stage_from_arc,
    metadata_stage_from_arc, middleware_stage_from_arc, rule_stage_from_arc, schema_stage_from_arc,
};

/// 提供器选择器
///
/// 通过项目阶段 / 项目 ID / 租户 / 区域编码筛选匹配的提供器，支持差异化配置。
#[derive(Debug, Clone, Default)]
pub struct ProviderSelector {
    pub phase: Option<ProjectPhase>,
    pub project_id: Option<String>,
    pub tenant_id: Option<String>,
    pub region_code: Option<String>,
}

impl ProviderSelector {
    /// 全量匹配
    pub fn any() -> Self {
        Self::default()
    }

    /// 指定阶段
    pub fn phase(
        mut self,
        phase: ProjectPhase,
    ) -> Self {
        self.phase = Some(phase);
        self
    }

    /// 指定项目
    pub fn project_id(
        mut self,
        project_id: impl Into<String>,
    ) -> Self {
        self.project_id = Some(project_id.into());
        self
    }

    /// 指定租户
    pub fn tenant_id(
        mut self,
        tenant_id: impl Into<String>,
    ) -> Self {
        self.tenant_id = Some(tenant_id.into());
        self
    }

    /// 指定区域
    pub fn region_code(
        mut self,
        region_code: impl Into<String>,
    ) -> Self {
        self.region_code = Some(region_code.into());
        self
    }

    /// 判断是否匹配当前项目
    fn matches(
        &self,
        profile: &ProjectProfile,
    ) -> bool {
        if let Some(phase) = &self.phase {
            if phase != &profile.phase {
                return false;
            }
        }
        if let Some(project_id) = &self.project_id {
            if project_id != &profile.project_id {
                return false;
            }
        }
        if let Some(tenant_id) = &self.tenant_id {
            if profile.tenant_id.as_deref() != Some(tenant_id.as_str()) {
                return false;
            }
        }
        if let Some(region_code) = &self.region_code {
            match profile.region.as_ref() {
                Some(region) if region.code == *region_code => {},
                _ => return false,
            }
        }
        true
    }
}

/// 注册表内部条目包装
struct Entry<T: ?Sized> {
    selector: ProviderSelector,
    provider: Arc<T>,
}

impl<T: ?Sized> Entry<T> {
    fn new(
        selector: ProviderSelector,
        provider: Arc<T>,
    ) -> Self {
        Self { selector, provider }
    }
}

/// 引导注册表
///
/// 负责管理八类提供器，并在构建 Loader 时按项目画像筛选出有效的阶段链。
///
/// # 提供器类型
///
/// 1. ExtensionProvider - 节点/schema 定义
/// 3. RuleProvider - 规则加载器
/// 4. DataSourceProvider - 数据源
/// 5. MetadataProvider - 元数据
/// 6. EventHandlerProvider - 事件处理器
/// 7. MiddlewareProvider - 中间件
/// 8. ForgeConfigProvider - Forge 性能配置
pub struct BootstrapRegistry {
    schema: Vec<Entry<dyn ExtensionProvider>>,
    rules: Vec<Entry<dyn RuleProvider>>,
    data_sources: Vec<Entry<dyn DataSourceProvider>>,
    metadata: Vec<Entry<dyn MetadataProvider>>,
    event_handlers: Vec<Entry<dyn EventHandlerProvider>>,
    middleware: Vec<Entry<dyn MiddlewareProvider>>,
    forge_configs: Vec<Entry<dyn ForgeConfigProvider>>,
}

impl Default for BootstrapRegistry {
    fn default() -> Self {
        Self::new()
    }
}

impl BootstrapRegistry {
    /// 创建空注册表
    pub fn new() -> Self {
        Self {
            schema: Vec::new(),
            rules: Vec::new(),
            data_sources: Vec::new(),
            metadata: Vec::new(),
            event_handlers: Vec::new(),
            middleware: Vec::new(),
            forge_configs: Vec::new(),
        }
    }

    /// 注册 schema 提供器
    pub fn register_schema<P>(
        &mut self,
        selector: ProviderSelector,
        provider: P,
    ) where
        P: ExtensionProvider + 'static,
    {
        self.schema.push(Entry::new(selector, Arc::new(provider)));
    }

    /// 注册规则提供器
    pub fn register_rule<P>(
        &mut self,
        selector: ProviderSelector,
        provider: P,
    ) where
        P: RuleProvider + 'static,
    {
        self.rules.push(Entry::new(selector, Arc::new(provider)));
    }

    /// 注册数据源提供器
    pub fn register_data_source<P>(
        &mut self,
        selector: ProviderSelector,
        provider: P,
    ) where
        P: DataSourceProvider + 'static,
    {
        self.data_sources.push(Entry::new(selector, Arc::new(provider)));
    }

    /// 注册元数据提供器
    pub fn register_metadata<P>(
        &mut self,
        selector: ProviderSelector,
        provider: P,
    ) where
        P: MetadataProvider + 'static,
    {
        self.metadata.push(Entry::new(selector, Arc::new(provider)));
    }

    /// 注册事件处理器提供器
    pub fn register_event_handler<P>(
        &mut self,
        selector: ProviderSelector,
        provider: P,
    ) where
        P: EventHandlerProvider + 'static,
    {
        self.event_handlers.push(Entry::new(selector, Arc::new(provider)));
    }

    /// 注册中间件提供器
    pub fn register_middleware<P>(
        &mut self,
        selector: ProviderSelector,
        provider: P,
    ) where
        P: MiddlewareProvider + 'static,
    {
        self.middleware.push(Entry::new(selector, Arc::new(provider)));
    }

    /// 注册 Forge 配置提供器
    pub fn register_forge_config<P>(
        &mut self,
        selector: ProviderSelector,
        provider: P,
    ) where
        P: ForgeConfigProvider + 'static,
    {
        self.forge_configs.push(Entry::new(selector, Arc::new(provider)));
    }

    /// 根据项目画像构建加载器及其阶段链
    ///
    /// 构建顺序：
    /// Schema → DataSource → Plugin → Metadata → EventHandler → Middleware → ForgeConfig → Rule
    ///
    /// 注意：EventHandler 和 Middleware 在 ForgeConfig 之前执行，
    /// ForgeConfig 在 Rule 之前执行，这样规则加载器可以根据配置进行初始化。
    pub fn build_loader(
        &self,
        profile: &ProjectProfile,
    ) -> BootstrapLoader {
        let mut builder = BootstrapLoader::builder();

        // 1. Schema 阶段
        for entry in self.schema.iter().filter(|e| e.selector.matches(profile)) {
            builder.add_stage(schema_stage_from_arc(Arc::clone(&entry.provider)));
        }

        // 2. DataSource 阶段
        for entry in self.data_sources.iter().filter(|e| e.selector.matches(profile)) {
            builder.add_stage(data_source_stage_from_arc(Arc::clone(&entry.provider)));
        }

        // 4. Metadata 阶段
        for entry in self.metadata.iter().filter(|e| e.selector.matches(profile)) {
            builder.add_stage(metadata_stage_from_arc(Arc::clone(&entry.provider)));
        }

        // 5. EventHandler 阶段
        for entry in self.event_handlers.iter().filter(|e| e.selector.matches(profile)) {
            builder.add_stage(event_handler_stage_from_arc(Arc::clone(&entry.provider)));
        }

        // 6. Middleware 阶段
        for entry in self.middleware.iter().filter(|e| e.selector.matches(profile)) {
            builder.add_stage(middleware_stage_from_arc(Arc::clone(&entry.provider)));
        }

        // 7. ForgeConfig 阶段
        for entry in self.forge_configs.iter().filter(|e| e.selector.matches(profile)) {
            builder.add_stage(forge_config_stage_from_arc(Arc::clone(&entry.provider)));
        }

        // 8. Rule 阶段
        for entry in self.rules.iter().filter(|e| e.selector.matches(profile)) {
            builder.add_stage(rule_stage_from_arc(Arc::clone(&entry.provider)));
        }

        builder.build()
    }
}
